1. Field of the Invention
This invention relates to computer software, and more particularly to a system and method for providing dynamic class reloading in applications.
2. Description of the Related Art
It is often necessary to make changes in the presentation logic and/or the business logic of applications. In the world of application servers that run large and often mission-critical applications, taking the server offline to get these changes reflected may not be possible. In the development environment, it is quite common for a developer to deploy an application or Enterprise JavaBeans™ (EJB™) bean, test it, and make certain changes to get desired results. Since deploying a business component like an EJB™ or assembling an application in itself is quite complex, in the development environment, whenever the developer changes a bean, the server has to be restarted to check the changes.
In application servers based on the J2EE™ (Java™ 2 Platform, Enterprise Edition) distributed computing model, the business presentation is typically represented using servlets and/or JavaServer Pages™ (JSP™), and the business logic typically runs in the form of distributed components such as EJBs. These application servers may, to an extent, provide for the reloading of servlets and JSPs at runtime through a custom class loader mechanism. The existing class loader framework is, however, based on older technologies, and versionabilty is provided assuming that there is no need for state maintenance of the components. The versionability criterion for classes is static and global for all applications.
A possible architecture for a class reloading mechanism is to have a separate class loader for each application, and to have the system class loader as the parent of the class loaders. The system class loader loads the standard classes and the application server core classes, and the application class loader loads the user-defined classes. This architecture is illustrated in FIG. 1. This architecture may addresses security and reloading issues, but does not provide an optimal class loading framework. Since there is a single class loader that handles all the classes in an application, all the loaded classes will be reloaded for a single class change. This is added overhead for the application server.
Class Loaders
The following section provides background information on class loaders, class loading, and class reloading, This information refers to the Java™ programming language and to the Java™ Virtual Machine (JVM) architecture as an example of an implementation of class loaders, loading, and reloading. This information, however, may be relevant to other architectures, programming languages, environments including virtual machine environments, platforms, applications, application servers and/or implementations of class loaders.
The default class loading mechanism in the JVM is to load the class file from a specified location into the memory and to execute the byte code as and when the request comes in for a particular class. The default class loader, which may be referred to as a system class loader, caches the class once it loads it. Therefore, if the class file changes after loading the class, the changes are not reflected in the program unless JVM is restarted.
Class loaders are one of the cornerstones of virtual machine architectures such as the JVM architecture. Class loaders enable a virtual machine to load classes without knowing anything about the underlying file system semantics, and may also allow applications to dynamically load classes such as Java™ classes as extension modules. For example, JVM has an embedded class loader called the primordial/system class loader. Virtual machines such as JVM may also provide a facility by which user can introduce a custom class loader. For example, in JVM, a hook is provided to the loading mechanism through the custom class loaders. A custom class loader may load a class before the primordial class loader does. Therefore, certain policies pertaining to loading classes, maintenance, fetching classes, etc. may be implemented by the custom class loader. The custom class loader may also, for example, specify the remote location from which the classes are loaded, and/or assign appropriate security. Programmatically speaking, class loaders are ordinary objects that may be defined in code (e.g. Java™ code). In Java™, class loaders are instances of subclasses of abstract class Classloader.
In Java™, classes and interfaces are dynamically loaded, linked, and initialized. Loading is the process of finding the binary form of a class or interface type with a particular name and constructing, from that binary form, a Class object to represent the class or interface. For example, a class or Interface C's loading is triggered by another class or interface D, which references C through its runtime constant pool. Class or interface loading may also be triggered by D invoking methods in certain Java™ class libraries such as Reflection. Once a class is loaded, it is linked and resolved. Linking involves verifying and preparing a class, its direct superinterfaces, its direct superclass and its element type (if its an array type). Resolving is the process of dynamically determining concrete values from symbolic references in the runtime constant pool is known as resolving.
A class object loaded by loader L1 has a runtime signature <C1,L1> inside JVM. Same class C1, when loaded by L2, has the runtime signature <C1,L2> and thus can be distinguished from <C1,L1> by its runtime signature.
Once a class loader loads a class, the same class loader cannot load a different version of the class, as JVM internally tightly couples the class with the class loader. To maintain type safety, the virtual machine must be able to consistently obtain the same class type for a given class name and loader. The virtual machine cannot trust any user-defined loadClass method to consistently return the same type for a given name. JVM has to ensure security and behavioral consistency. Therefore, the virtual machine internally maintains a loaded class cache. The loaded class cache maps class names and the initiating loaders.
The next time the loader tries to load the class, an already cached copy of the class will be returned, but reloading will not be performed. So to reload a class requires the class to be loaded by a new loader. A runtime class type is determined not by its name alone but by its class name and its defining class loader. So if two loaders L1 and L2 load a class, they are different.
Delegation Mechanism
The Java™ Development Kit (JDK™), version 1.2, introduces a delegation mechanism that was not provided by earlier versions of the JDK. When using many class loaders, the class loaders can be linked using a parent-child relationship. A loader, before trying to load a class, can forward the request to its parent. The loading of a class can be started by one loader and completed by another. If C is a result of the loadClass of loader Li, then Li is the initiating loader of C. If C is the result of the defineClass( ) of loader Ld, then Ld is the defining loader of C.
In the following, the class type is shown as <C,Ld> where C is the Class and Ld is the defining loader. CLi is used to depict the initiation of loading.
Consider an example with loaders L1 and L2, and classes C1, C2.
class C1{String s1 = “xyz”;void g(){C2 c2obj= new C2();C2obj.f( s1 );}}class C2{void f(String s ){.....}}
If C1 was loaded by L1 and C2 was loaded by L2, the symbolic reference of String inside C1 will be resolved by L1 (i.e. String class will be loaded by L1). C2 is loaded by L2. When a call happens to function f of C2 inside C1, the argument passed is <String, L1>, but the argument expected by f inside C2 is <String, L2> and there would be a class cast exception when trying to making a call. This problem happens because two different types of the same class were being used as one. This redundancy can be reduced by providing a parent class loader Lp to the loaders, which will take the responsibility of loading all the common classes that it can. Thus, both L1 and L2 will forward the request to Lp and will effectively end up loading String through Lp only once, thus maintaining consistency.
Framework of a Loader
The main methods in ClassLoader are:
public Class loadClass( String name)protected final Class defineClass(String name, byte[] buf,int off, int len);protected final Class findLoadedClass(String name)protected final Class findSystemClass (String name)protected Class findClass (String className)Resolution Mechanism
As previously mentioned, resolution is the dynamic determination of symbolic references. The following example illustrates the resolution for a class C.
Class C extends D implements E {F f ;String s;C(){S = f.myString;}void myMethod(){f.itsMethod();}}direct superInteface: Edirect superClass : Dexternal class SymbolicReference : Fexternal Field Symbolic Reference : F::myStringexternal Method Symbolic Reference : F::itsMethod()
Direct superClass and direct superInterface are loaded at the time of the loading of C using the same loadClass of the loader which called a defineClass for C. Other Symbolic references are dynamically resolved.
Class: The defining loader of C is used to load this class.
Field: First the class to which field belongs is resolved. Then the field resolution attempts to look up the referenced field in the class and all its superclasses.
Constraints imposed: let <E, L1> be the class or interface in which the referenced field is actually declared and let L2 be the defining loader of D. Let T be the name of the type of the referenced field. The virtual machine imposes the loading constraint:                T(L1)=T(L2).        
First the class on which the method is called is resolved. After the class is resolved, the method is looked up in the class, its super classes or super interfaces. The following constraints may be applied. Let <E, L1> be the class or interface in which the referenced method is actually declared and let L2 be the defining loader of D. Let T0 be the name of the type returned by the referenced method, and let T1 . . . Tn be the names of the argument types of the referenced method. The virtual machine imposes the loading constraint:                for i=1 to n:                    TiL1=TiL2J2EE™                        
The Java™ 2 Platform, Enterprise Edition (J2EE™) defines the standard for developing multitier enterprise Applications. J2EE™ simplifies enterprise applications by basing them on standardized, modular components, by providing a complete set of services to those components, and by handling many details of application behavior automatically, without complex programming. J2EE™ takes advantage of many features of the Java™ 2 Platform, Standard Edition, such as “Write Once, Run Anywhere™” portability, JDBC™ (Java™ DataBase Connectivity) API for database access, Object Management Group's Common Object Request Broker Architecture (CORBA) technology for interaction with existing enterprise resources, and a security model that protects data even in internet applications. Building on this base, J2EE™ adds full support for EJB™ components, Java™ Servlets API, and JSP™ among many other technologies.
Enterprise JavaBeans™ (EJB™)
EJB™ is a component architecture for the development and deployment of object-oriented, distributed, enterprise-level applications. Applications written using the EJB™ architecture are scalable, transactional, and secure.
JavaServer Pages™ (JSP™)
JSP™ is an extensible web technology that uses template data, custom elements, scripting languages, and server-side Java objects to return dynamic content to a client. Typically the template data is HTML or XML elements, and in many cases the client is a web browser.
Servlets
A servlet may be generally defined as a small program that runs on a server. In Java™, a servlet is a Java™ program that extends the functionality of a web server, generating dynamic content and interacting with web clients using a request-response paradigm.
J2EE™ Applications
A J2EE™ application may be defined as a deployable unit of J2EE™ functionality. This can be a single module or a group of modules packaged into an .ear file with a J2EE™ application deployment descriptor. J2EE™ applications are typically engineered to be distributed across multiple tiers in an n-tier computing model
Modules
In programming, a module may be a unit of code that may be maintained and reused by different programs. Modular programming is the concept that similar functions should be contained within the same unit of programming code (a module), and that separate functions should be developed as separate units of code (modules), so that the code can easily be maintained and reused by different programs. Object-oriented programming inherently encompasses modular programming. J2EE™ is an example of an environment that may use modular programming.
J2EE™ Module
A software unit that consists of one or more J2EE™ components of the same container type and one deployment descriptor of that type. There are three types of modules: EJB™, web, and application client. Modules can be deployed as stand-alone units or assembled into an application.
Container
An entity that provides life cycle management, security, deployment, and runtime services to components. Corresponding to every component type, there exists a container. Each type of container (e.g. EJB™, web, JSP™, servlet, applet, and application client) may provide component-specific services.
Application Servers
An application server is a server program in a computer in a distributed network that provides the business logic for an application program. The application server is frequently viewed as part of a three-tier application, consisting of a graphical user interface (GUI) server, an application (business logic) server, and a database server. More descriptively, it can be viewed as dividing an application into:                A first-tier, front-end, Web browser-based graphical user interface, usually at a personal computer or workstation        A middle-tier business logic application or set of applications, possibly on a local area network or intranet server        A third-tier, back-end, database and transaction server, sometimes on a mainframe or large server        
Older, legacy application databases and transaction management applications are part of the back end or third tier. The application server is the middleman between browser-based front-ends and back-end databases and legacy systems.
iPlanet™ Application Server (iAS™)
The iPlanet™ Application Server (iAS™), offered by iPlanet E-Commerce Solutions, provides a robust J2EE™ e-commerce platform for the development, deployment, and management of application services to a broad range of servers, clients, and devices. iAS™ maximizes application re-use and developer collaboration and demonstrates the potential of leveraging Java™ for large-scale web and wireless applications.